package ru.ifmo.trafficspy.provider;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import ru.ifmo.trafficspy.common.Interval;
import ru.ifmo.trafficspy.common.Item;
import ru.ifmo.trafficspy.common.Packet;

public class ProviderWithNoise extends Provider {

	private class Pair implements Comparable<Pair> {
		final int time;
		final Packet packet;
		
		public Pair(int time, Packet packet) {
			this.time = time;
			this.packet = packet;
		}
		
		public int compareTo(Pair o) {
			return time - o.time;
		}
		
	}
	
	private final Provider innerProvider;
	
	private int minPacketSize;
	private int maxPacketSize;
	private int minGapSize;
	private int maxGapSize;
	
	public ProviderWithNoise(Provider innerProvider, String description) {
		super(description);
		this.innerProvider = innerProvider;
	}

	@Override
	public List<Item> getTraffic() {
		List<Item> traffic = innerProvider.getTraffic();
		ArrayList<Pair> list = new ArrayList<Pair>();
		int curTime = 0;
		for (int i = 0; i < traffic.size(); i++) {
			if (i % 2 == 0) {
				list.add(new Pair(curTime, (Packet) traffic.get(i)));
			} else {
				curTime += traffic.get(i).getValue();
			}
		}
		Random r = new Random();
		int time = r.nextInt(maxGapSize - minGapSize + 1);
		while (time <= curTime) {
			list.add(new Pair(time, new Packet(minPacketSize + r.nextInt(maxPacketSize - minPacketSize + 1))));
			time += minGapSize + r.nextInt(maxGapSize - minGapSize + 1);
		}
		Collections.sort(list);
		
		ArrayList<Item> newTraffic = new ArrayList<Item>();		
		newTraffic.add(list.get(0).packet);		
		for (int i = 1; i < list.size(); i++) {
			newTraffic.add(new Interval(list.get(i).time - list.get(i - 1).time));
			newTraffic.add(list.get(i).packet);
		}
		return newTraffic;
	}

}
